import {
  _decorator,
  Component,
  instantiate,
  IVec2,
  Node,
  Tween,
  UITransform,
  Vec2,
  Vec3,
} from "cc";
import DataManager from "../../Global/DataManager";
import { EntityTypeEnum, IActor, IBullet, InputTypeEnum } from "../../Common";
import { EntityManager } from "../../Base/EntityManager";
import { BulletStateMananger } from "./BulletStateMananger";
import { ActorStateEnum, EventEnum } from "../../Enum";
import EventManager from "../../Global/EventManager";
import { rad2Angle } from "../../Utils";
import { ExplosionManager } from "../Explosion/ExplosionManager";
import ObjectPoolManager from "../../Global/ObjectPoolManager";
const { ccclass, property } = _decorator;

@ccclass("BulletManager")
export class BulletManager extends EntityManager {
  owner: number;

  type: EntityTypeEnum;
  id: number;

  targetPos: Vec3;
  tw: Tween<Node>;

  start() {}

  init(data: IBullet) {
    this.type = data.type;
    this.id = data.id;

    this.fsm = this.node.addComponent(BulletStateMananger);
    this.fsm.init(data.type);
    this.state = ActorStateEnum.Idle;

    this.node.active = false;
    this.targetPos = undefined;

    EventManager.Instance.on(EventEnum.ExplosionBurn, this.onExplosion, this);
  }

  onExplosion(id: number, { x, y }: IVec2) {
    if (id != this.id) {
      return;
    }

    let newExplo = ObjectPoolManager.Instance.get(EntityTypeEnum.Explosion);

    let exploMgr =
      newExplo.getComponent(ExplosionManager) ||
      newExplo.addComponent(ExplosionManager);
    exploMgr.init(EntityTypeEnum.Explosion, {
      x,
      y,
    });

    EventManager.Instance.off(EventEnum.ExplosionBurn, this.onExplosion, this);
    DataManager.Instance.mapBullet.delete(this.id);

    ObjectPoolManager.Instance.ret(this.node);
  }

  render(data: IBullet) {
    const { direction } = data;

    this.renderPosition(data);

    // let side = Math.sqrt(direction.x ** 2 + direction.y ** 2);
    let angle = rad2Angle(Math.atan2(direction.y, direction.x));
    this.node.setRotationFromEuler(0, 0, angle);
  }

  renderPosition({ position }: IBullet) {
    const newPos = new Vec3(position.x, position.y);

    if (!this.targetPos) {
      this.node.active = true;
      this.node.setPosition(newPos);
      this.targetPos = new Vec3(newPos);
    } else if (!newPos.equals(this.targetPos)) {
      this.node.setPosition(this.targetPos);
      this.targetPos.set(newPos);

      this.tw?.stop();
      this.tw = new Tween(this.node).to(0.1, { position: newPos }).start();
    }

    this.node.setPosition(position.x, position.y);
  }

  protected onDestroy(): void {
    EventManager.Instance.off(EventEnum.ExplosionBurn, this.onExplosion, this);
  }
}
